//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <bulverde.h>
#include "misc.h"
#include "i2s.h"

// TCS2302 in Format 3 20-bit & BV in Figure 14-1 I2S 16 bits
// SYNC low for left channel and high for right
// DATA[31:16] for right channel and DATA[15:0] for left
// When send data out, invalid data bits will be '0' at I2S_D_OUT

//    BV_SASR0 = ;
//    BV_SAIMR = ;
//    BV_SAICR = ;

#define I2S_ENABLE           (BV_SACR0 |=  SACR0_ENB)
#define I2S_DISABLE          (BV_SACR0 &=~ SACR0_ENB)
#define CLK_I2S_ENABLE                (CKEN |=  CKEN8_I2S)
#define CLK_I2S_DISABLE               (CKEN &=~ CKEN8_I2S)

void I2S_GPIO(void)
{
	GPSR0 |= GP028_I2SBITCLK|GP030_I2SDATAOUT|GP031_I2SSYNC|GP029_I2SDATAIN;
	GPSR3 |= GP113_I2SSYSCLK;
	GPDR0 |= GP028_I2SBITCLK|GP030_I2SDATAOUT|GP031_I2SSYNC;
	GPDR3 |= GP113_I2SSYSCLK;
	GPDR0 &=~GP029_I2SDATAIN;
	//here is some ugly code
	GAFR0_U &= ~((3<<24)|(3<<26)|(3<<28)|(3<<30));
	GAFR3_U &= ~(3<<2);
	//
	GAFR0_U |=(1<<24)|(2<<26)|(1<<28)|(1<<30);
	GAFR3_U |=(1<<2);

}

void I2S_GPIOClose(void)
{
	GPCR0 |= GP028_I2SBITCLK|GP030_I2SDATAOUT|GP031_I2SSYNC|GP029_I2SDATAIN;
	GPCR3 |= GP113_I2SSYSCLK;
}


void I2S_PrePlay(void)
{

	CLK_I2S_ENABLE;
    BV_SACR1 = SACR1_DREC;
//    BV_SADIV = I2S_SAM_FEQ_22;

    BV_SACR0 = (7 * SACR0_TFTH) | (7 * SACR0_RFTH) | (SACR0_BCKD);    // I2S_BITCLK output
    I2S_ENABLE;

}

void I2S_AftPlay(void)
{
    I2S_DISABLE;

    // wait until all the data have been send out
    while(BV_SASR0 & SASR0_OFF)  { ; }

    BV_SACR0 = SACR0_RST;

    CLK_I2S_DISABLE;
}

#ifdef AUDIO_TEST
void I2S_PlayDebug(unsigned long data, unsigned long dwNum)
{
    unsigned long i;

    for(i=0;i<dwNum;i++)
    {
        // wait until TX FIFO is not full
        while(!(BV_SASR0 & SASR0_TNF)){ ; }

        BV_SADR = data;
    }
}

void I2S_Play(unsigned long * pData, unsigned long dwNum)
{
    unsigned long i;


    for(i=0;i<dwNum;i++)
    {
        // wait until TX FIFO is not full
        while(!(BV_SASR0 & SASR0_TNF)){ ; }

        BV_SADR = pData[i];
    }
}
#endif

void I2S_PreRecord(void)
{
	CLK_I2S_ENABLE;
    BV_SACR1 = SACR1_DRPL;
//    BV_SADIV = I2S_SAM_FEQ_22;

    BV_SACR0 = (7 * SACR0_TFTH) | (7 * SACR0_RFTH) | (SACR0_BCKD);    // I2S_BITCLK output
    I2S_ENABLE;

}

void I2S_AftRecord(void)
{
    volatile unsigned long t;

    I2S_DISABLE;

    // wait for I2S idle or disable
    while(BV_SASR0 & SASR0_BSY)  { ; }

    while(BV_SASR0 & SASR0_RNE)
    {
        t = BV_SADR;
    }

    BV_SACR0 = SACR0_RST;

    CLK_I2S_DISABLE;
}

#ifdef AUDIO_TEST
/*
*	Input: buffer address
*	Return: Data recorded length
*/
unsigned int I2S_Record(unsigned long * pData)
{
    unsigned long i;
	i =0;
 while(!serial_poll())
    {
        // wait until RX FIFO is not empty
        while(!(BV_SASR0 & SASR0_RNE)){ ; }

        pData[i++] = BV_SADR;
	}
 	return i;
}
#endif
